﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace QuickPhotoFilter
{
    /// <summary>
    /// Логика взаимодействия для MainWindow.xaml
    /// </summary>
    /// 
    enum ActiveColor { Color1, Color2 }

    public partial class MainWindow : Window
    {
        QPF qpf;
        ActiveColor activeColor = ActiveColor.Color1;
        Point mouseButtonDownPoint;
        bool leftMouseButtonIsDown = false, rightMouseButtonIsDown = false;
        MouseButton activeMouseButton = MouseButton.Middle; // т.к. средняя кнопка в приложении не используется
        int zoomFrameNormalWidth = 300, zoomFrameNormalHeight = 200;
        Rectangle zoomFrame, previousZoomFrame;
        Point mousePreviousPoint, mouseCurrentPoint;

        public MainWindow()
        {
            InitializeComponent();
            qpf = new QPF(workspace);
            currentColor1Button.Background = new SolidColorBrush(qpf.CurrentColor1);
            currentColor2Button.Background = new SolidColorBrush(qpf.CurrentColor2);
        }

        private void markedAreaTypeButton_Click(object sender, RoutedEventArgs e)//открытие контекстного меню
        {
            (sender as Button).ContextMenu.IsEnabled = true;
            (sender as Button).ContextMenu.PlacementTarget = (sender as Button);
            (sender as Button).ContextMenu.Placement = System.Windows.Controls.Primitives.PlacementMode.Bottom;
            (sender as Button).ContextMenu.IsOpen = true;
        }

        private void currentWidthButton_Click(object sender, RoutedEventArgs e)//открытие контекстного меню
        {
            (sender as Button).ContextMenu.IsEnabled = true;
            (sender as Button).ContextMenu.PlacementTarget = (sender as Button);
            (sender as Button).ContextMenu.Placement = System.Windows.Controls.Primitives.PlacementMode.Bottom;
            (sender as Button).ContextMenu.IsOpen = true;
        }

        private void fileButton_Click(object sender, RoutedEventArgs e)//открытие контекстного меню
        {
            (sender as Button).ContextMenu.IsEnabled = true;
            (sender as Button).ContextMenu.PlacementTarget = (sender as Button);
            (sender as Button).ContextMenu.Placement = System.Windows.Controls.Primitives.PlacementMode.Bottom;
            (sender as Button).ContextMenu.IsOpen = true;
        }

        private void openFileMenuItem_Click(object sender, RoutedEventArgs e)
        {
            Microsoft.Win32.OpenFileDialog openFileDialogWindow = new Microsoft.Win32.OpenFileDialog();
            openFileDialogWindow.Multiselect = false;
            openFileDialogWindow.DefaultExt = ".jpg";
            openFileDialogWindow.Filter = "JPEG |*.jpg; *.jpeg; *jpe|BMP |*.bmp|GIF |*.gif|PNG|*.png|TIFF|*.tiff; *.tif|All files|*";
            Nullable<bool> result = openFileDialogWindow.ShowDialog();
            if (result != null && result != false)
            {
                string exceptionMessage;
                if (!qpf.LoadPictureFromFile(openFileDialogWindow.FileName, out exceptionMessage))
                    MessageBox.Show(exceptionMessage, "Ошибка открытия файла", MessageBoxButton.OK, MessageBoxImage.Error);
                else
                {
                    scrollViewer.ScrollToLeftEnd();
                    scrollViewer.ScrollToTop();
                    this.Title = qpf.FileName.Substring(qpf.FileName.LastIndexOf('\\') + 1) + " - QuickPhotoFilter";
                }

            }
        }

        private void saveAsFileMenuItem_Click(object sender, RoutedEventArgs e) { saveFileAs(); }

        private void saveFileMenuItem_Click(object sender, RoutedEventArgs e)
        {
            if (qpf.FileName != null && qpf.FileName != string.Empty)
            {
                string exceptionMessage;
                if (!qpf.SaveFileAs(qpf.FileName, out exceptionMessage))
                    MessageBox.Show(exceptionMessage, "Ошибка сохранения файла", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            else
                saveFileAs();
        }

        void saveFileAs()
        {
            Microsoft.Win32.SaveFileDialog saveAsFileDialogWindow = new Microsoft.Win32.SaveFileDialog();
            saveAsFileDialogWindow.FileName = "Picture";
            saveAsFileDialogWindow.DefaultExt = ".jpg";
            saveAsFileDialogWindow.Filter = "BMP |*.bmp|JPEG |*.jpg; *.jpeg; *jpe|GIF |*.gif|PNG|*.png|TIFF|*.tiff; *.tif";
            Nullable<bool> result = saveAsFileDialogWindow.ShowDialog();
            if (result != null && result != false)
            {
                string exceptionMessage;
                if (!qpf.SaveFileAs(saveAsFileDialogWindow.FileName, out exceptionMessage))
                    MessageBox.Show(exceptionMessage, "Ошибка сохранения файла", MessageBoxButton.OK, MessageBoxImage.Error);
                else
                    this.Title = qpf.FileName.Substring(qpf.FileName.LastIndexOf('\\') + 1) + " - QuickPhotoFilter";
            }
        }

        private void workspace_MouseDown(object sender, MouseButtonEventArgs e)
        {
            mouseButtonDownPoint = e.GetPosition(workspace);
            if (e.ChangedButton == MouseButton.Left)
                leftMouseButtonIsDown = true;
            if (e.ChangedButton == MouseButton.Right)
                rightMouseButtonIsDown = true;
            activeMouseButton = e.ChangedButton;
            switch (qpf.ActiveTool)
            {
                case Tool.Scale:
                    if (e.ChangedButton == MouseButton.Left)
                        qpf.ZoomIn();
                    if (e.ChangedButton == MouseButton.Right)
                        qpf.ZoomOut();
                    scrollViewer.ScrollToHorizontalOffset(mouseButtonDownPoint.X * qpf.Scale - scrollViewer.ActualWidth / 2);
                    scrollViewer.ScrollToVerticalOffset(mouseButtonDownPoint.Y * qpf.Scale - scrollViewer.ActualHeight / 2);
                    break;
                case Tool.Pen:
                    if (leftMouseButtonIsDown)
                    {
                        qpf.DrawPoint(mouseButtonDownPoint, qpf.CurrentColor1);
                        mousePreviousPoint = mouseButtonDownPoint;
                    }
                    if (rightMouseButtonIsDown)
                    {
                        qpf.DrawPoint(mouseButtonDownPoint, qpf.CurrentColor2);
                        mousePreviousPoint = mouseButtonDownPoint;
                    }
                    break;
                case Tool.Pipette:
                    if (leftMouseButtonIsDown)
                    {
                        qpf.CurrentColor1 = qpf.DetermineColor(mouseButtonDownPoint);
                        currentColor1Button.Background = new SolidColorBrush(qpf.CurrentColor1);
                    }
                    else if (rightMouseButtonIsDown)
                    {
                        qpf.CurrentColor2 = qpf.DetermineColor(mouseButtonDownPoint);
                        currentColor2Button.Background = new SolidColorBrush(qpf.CurrentColor2);
                    }
                    break;
                case Tool.Eraser:
                    if (leftMouseButtonIsDown)
                    {
                        qpf.DrawPoint(mouseButtonDownPoint, Colors.White);
                        mousePreviousPoint = mouseButtonDownPoint;
                    }
                    break;
                case Tool.Fill:
                    if (leftMouseButtonIsDown)
                    {
                        qpf.FillArea(mouseButtonDownPoint);
                    }
                    break;
            }
        }

        private void workspace_MouseMove(object sender, MouseEventArgs e)
        {
            mouseCurrentPoint = e.GetPosition(workspace);
            switch (qpf.ActiveTool)
            {
                case Tool.Pen:
                    if ((leftMouseButtonIsDown || rightMouseButtonIsDown) &&
                        (mouseCurrentPoint.X < workspace.Width && mouseCurrentPoint.X >= 0) &&
                        (mouseCurrentPoint.Y < workspace.Width && mouseCurrentPoint.Y >= 0))
                    {
                        Color color = new Color();
                        if (activeMouseButton == MouseButton.Left)
                            color = qpf.CurrentColor1;
                        if (activeMouseButton == MouseButton.Right)
                            color = qpf.CurrentColor2;
                        qpf.DrawLine(mouseCurrentPoint, mousePreviousPoint, color);
                    }
                    break;
                case Tool.Scale:
                    double zoomFrameOptWidth = zoomFrameNormalWidth / qpf.Scale, zoomFrameOptHeight = zoomFrameNormalHeight / qpf.Scale;
                    zoomFrame = new Rectangle
                    {
                        Stroke = new SolidColorBrush(qpf.InvertColor(qpf.DetermineColor(e.GetPosition(workspace)))),
                        StrokeThickness = 1 / qpf.Scale
                    };
                    if (workspace.ActualWidth < zoomFrameOptWidth || workspace.ActualHeight < zoomFrameOptHeight)
                    {
                        Canvas.SetLeft(zoomFrame, 0);
                        Canvas.SetTop(zoomFrame, 0);
                        zoomFrame.Width = workspace.ActualWidth;
                        zoomFrame.Height = workspace.ActualHeight;
                    }
                    else
                    {
                        if (e.GetPosition(workspace).X - zoomFrameOptWidth / 2 < 0)
                            Canvas.SetLeft(zoomFrame, 0);
                        else
                            if (e.GetPosition(workspace).X + zoomFrameOptWidth / 2 > workspace.ActualWidth)
                                Canvas.SetLeft(zoomFrame, workspace.ActualWidth - zoomFrameOptWidth);
                            else
                                Canvas.SetLeft(zoomFrame, e.GetPosition(workspace).X - zoomFrameOptWidth / 2);
                        if (e.GetPosition(workspace).Y - zoomFrameOptHeight / 2 < 0)
                            Canvas.SetTop(zoomFrame, 0);
                        else
                            if (e.GetPosition(workspace).Y + zoomFrameOptHeight / 2 > workspace.ActualHeight)
                                Canvas.SetTop(zoomFrame, workspace.ActualHeight - zoomFrameOptHeight);
                            else
                                Canvas.SetTop(zoomFrame, e.GetPosition(workspace).Y - zoomFrameOptHeight / 2);
                        zoomFrame.Width = zoomFrameOptWidth;
                        zoomFrame.Height = zoomFrameOptHeight;
                    }
                    workspace.Children.Add(zoomFrame);
                    if (previousZoomFrame != null)
                        workspace.Children.Remove(previousZoomFrame);
                    previousZoomFrame = zoomFrame;
                    break;
                case Tool.Eraser:
                    if (leftMouseButtonIsDown &&
                    (mouseCurrentPoint.X < workspace.Width && mouseCurrentPoint.X >= 0) &&
                    (mouseCurrentPoint.Y < workspace.Width && mouseCurrentPoint.Y >= 0))
                    {
                        qpf.DrawLine(mouseCurrentPoint, mousePreviousPoint, Colors.White);
                    }
                    break;
            }
            mousePreviousPoint = mouseCurrentPoint;
        }

        private void workspace_MouseLeave(object sender, MouseEventArgs e)
        {
            switch (qpf.ActiveTool)
            {
                case Tool.Scale:
                    workspace.Children.Remove(zoomFrame);
                    break;
                case Tool.Pen:
                    if (leftMouseButtonIsDown || rightMouseButtonIsDown)
                    {
                        mouseCurrentPoint = e.GetPosition(workspace);
                        if (mouseCurrentPoint != mousePreviousPoint) // равенство возможно при уходе в края окна
                        {
                            Color color = new Color();
                            if (activeMouseButton == MouseButton.Left)
                                color = qpf.CurrentColor1;
                            if (activeMouseButton == MouseButton.Right)
                                color = qpf.CurrentColor2;
                            qpf.DrawLine(mouseCurrentPoint, mousePreviousPoint, color);
                            mousePreviousPoint = mouseCurrentPoint;
                            Mouse.Capture(workspace);
                        }
                        else
                        {
                            leftMouseButtonIsDown = false;
                            rightMouseButtonIsDown = false;
                            activeMouseButton = MouseButton.Middle;
                        }
                    }
                    break;
            }
        }

        private void workspace_MouseEnter(object sender, MouseEventArgs e)
        {
            switch (qpf.ActiveTool)
            {
                case Tool.Pen:
                    if (e.LeftButton == MouseButtonState.Released)
                        leftMouseButtonIsDown = false;
                    if (e.RightButton == MouseButtonState.Released)
                        rightMouseButtonIsDown = false;
                    if (leftMouseButtonIsDown || rightMouseButtonIsDown)
                        mouseCurrentPoint = e.GetPosition(workspace);
                    break;
            }
        }
        private void workspace_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (e.ChangedButton == MouseButton.Left)
            {
                leftMouseButtonIsDown = false;
                if (rightMouseButtonIsDown)
                    activeMouseButton = MouseButton.Right;
                else
                    activeMouseButton = MouseButton.Middle;
            }
            if (e.ChangedButton == MouseButton.Right)
            {
                rightMouseButtonIsDown = false;
                if (leftMouseButtonIsDown)
                    activeMouseButton = MouseButton.Left;
                else
                    activeMouseButton = MouseButton.Middle;
            }
            if (!leftMouseButtonIsDown && !rightMouseButtonIsDown)
                Mouse.Capture(null);
        }

        private void penButton_Click(object sender, RoutedEventArgs e) { qpf.ActiveTool = Tool.Pen; }

        private void filterButton_Click(object sender, RoutedEventArgs e)
        {
            qpf.Filter();

            //Line line = new Line();
            //Point a = new Point(30, 100);
            //Point b = new Point(100, 100);

            //line.X1 = a.X;
            //line.Y1 = a.Y;
            //line.X2 = b.X;
            //line.Y2 = b.Y;
            //Canvas.SetLeft(line, 0);
            //Canvas.SetTop(line, 0);
            //line.Stroke = new SolidColorBrush(Colors.Red);
            //line.StrokeThickness = qpf.Thickness * 3 + 1;
            //line.Height = Math.Max(line.Y1, line.Y2);
            //line.Width = Math.Max(line.X1, line.X2);
            //qpf.RenderShape(line);
            //qpf.DrawPoint(a);
            //qpf.DrawPoint(b);
            //workspace.Children.Add(line);

            //    Ellipse rect = new Ellipse();
            //    rect.Width = 1000;
            //    rect.Height = 760;
            //    Canvas.SetLeft(rect, 24);
            //    Canvas.SetTop(rect, 8);
            //    rect.Fill = new SolidColorBrush(Colors.Red);
            //    qpf.RenderShape(rect);
        }

        private void fillButton_Click(object sender, RoutedEventArgs e)
        {
            /*Rectangle a = new Rectangle();
            a.Fill = new SolidColorBrush(Colors.White);
            Canvas.SetLeft(a, 0);
            Canvas.SetTop(a, 0);
            a.Width = 100;
            a.Height = 100;
            //qpf.Insert(el);
            qpf.RenderShape(a);*/
            qpf.ActiveTool = Tool.Fill;
        }

        private void markButton_Click(object sender, RoutedEventArgs e)
        {

        }
        private void scaleButton_Click(object sender, RoutedEventArgs e) { qpf.ActiveTool = Tool.Scale; }

        private void SetColorFromButton(Button button) // устанавливает цвет для Pen
        {
            if (activeColor == ActiveColor.Color1)
            {
                qpf.CurrentColor1 = ((button.Background as SolidColorBrush).Color);
                currentColor1Button.Background = new SolidColorBrush(qpf.CurrentColor1);
            }
            else
            {
                qpf.CurrentColor2 = ((button.Background as SolidColorBrush).Color);
                currentColor2Button.Background = new SolidColorBrush(qpf.CurrentColor2);
            }
        }


        private void currentColor1Button_Click(object sender, RoutedEventArgs e)
        {
            activeColor = ActiveColor.Color1;
            //currentColor1Button
        }

        private void currentColor2Button_Click(object sender, RoutedEventArgs e)
        {
            activeColor = ActiveColor.Color2;
        }

        private void whiteColorButton_Click(object sender, RoutedEventArgs e)
        {

        }

        private void maroonColorButton_Click(object sender, RoutedEventArgs e)
        {
            SetColorFromButton(maroonColorButton);
        }

        private void orangeRedColorButton_Click(object sender, RoutedEventArgs e)
        {
            SetColorFromButton(orangeRedColorButton);
        }

        private void greenColorButton_Click(object sender, RoutedEventArgs e)
        {
            SetColorFromButton(greenColorButton);
        }

        private void darkBlueColorButton_Click(object sender, RoutedEventArgs e)
        {
            SetColorFromButton(darkBlueColorButton);
        }

        private void blackColorButton_Click(object sender, RoutedEventArgs e)
        {
            SetColorFromButton(blackColorButton);
        }

        private void saddleBrownColorButton_Click(object sender, RoutedEventArgs e)
        {
            SetColorFromButton(saddleBrownColorButton);
        }

        private void orangeColorButton_Click(object sender, RoutedEventArgs e)
        {
            SetColorFromButton(orangeColorButton);
        }

        private void lawnGreenColorButton_Click(object sender, RoutedEventArgs e)
        {
            SetColorFromButton(lawnGreenColorButton);
        }

        private void purpleColorButton_Click(object sender, RoutedEventArgs e)
        {
            SetColorFromButton(purpleColorButton);
        }

        private void dimGrayColorButton_Click(object sender, RoutedEventArgs e)
        {
            SetColorFromButton(dimGrayColorButton);
        }

        private void redColorButton_Click(object sender, RoutedEventArgs e)
        {
            SetColorFromButton(redColorButton);
        }

        private void yellowColorButton_Click(object sender, RoutedEventArgs e)
        {
            SetColorFromButton(yellowColorButton);
        }

        private void royalBlueColorButton_Click(object sender, RoutedEventArgs e)
        {
            SetColorFromButton(royalBlueColorButton);
        }

        private void mediumPurpleColorButton_Click(object sender, RoutedEventArgs e)
        {
            SetColorFromButton(mediumPurpleColorButton);
        }

        private void darkGrayColorButton_Click(object sender, RoutedEventArgs e)
        {
            SetColorFromButton(darkGrayColorButton);
        }

        private void pinkColorButton_Click(object sender, RoutedEventArgs e)
        {
            SetColorFromButton(pickColorButton);
        }

        private void peachPuffColorButton_Click(object sender, RoutedEventArgs e)
        {
            SetColorFromButton(peachPuffColorButton);
        }

        private void lightSkyBlueColorButton_Click(object sender, RoutedEventArgs e)
        {
            SetColorFromButton(lightSkyBlueColorButton);
        }

        private void cadetBlueColorButton_Click(object sender, RoutedEventArgs e)
        {
            SetColorFromButton(cadetBlueColorButton);
        }

        private void eraserButton_Click(object sender, RoutedEventArgs e)
        {
            qpf.ActiveTool = Tool.Eraser;
        }

        private void pickColorButton_Click(object sender, RoutedEventArgs e)
        {
            qpf.ActiveTool = Tool.Pipette;
        }

        private void px1MenuItem_Click(object sender, RoutedEventArgs e)
        {
            qpf.Thickness = 0;
        }

        private void px3MenuItem_Click(object sender, RoutedEventArgs e)
        {
            qpf.Thickness = 1;
        }

        private void px5MenuItem_Click(object sender, RoutedEventArgs e)
        {
            qpf.Thickness = 2;
        }

        private void px7MenuItem_Click(object sender, RoutedEventArgs e)
        {
            qpf.Thickness = 3;
        }

        private void px9MenuItem_Click(object sender, RoutedEventArgs e)
        {
            qpf.Thickness = 4;
        }


    }
}
